package main

import (
	"encoding/json"
	"fmt"
	"log"
	"math/rand"
	"net/http"
	"strconv"
	"sync"
	"time"
)

// ============================ 数据结构定义 ============================

// Order 订单结构
type Order struct {
	ID          string    `json:"id"`
	UserID      string    `json:"user_id"`
	ProductID   string    `json:"product_id"`
	ProductName string    `json:"product_name"`
	Quantity    int       `json:"quantity"`
	TotalPrice  float64   `json:"total_price"`
	Status      string    `json:"status"`
	CreatedAt   time.Time `json:"created_at"`
	OrderType   string    `json:"order_type"` // normal, seckill, ai
}

// Product 商品结构
type Product struct {
	ID           string  `json:"id"`
	Name         string  `json:"name"`
	Price        float64 `json:"price"`
	Stock        int     `json:"stock"`
	IsHot        bool    `json:"is_hot"`
	SeckillStock int     `json:"seckill_stock"`
	SeckillPrice float64 `json:"seckill_price"`
}

// SeckillRequest 秒杀请求
type SeckillRequest struct {
	UserID    string `json:"user_id"`
	ProductID string `json:"product_id"`
}

// SeckillResult 秒杀结果
type SeckillResult struct {
	Success bool   `json:"success"`
	OrderID string `json:"order_id"`
	Message string `json:"message"`
}

// AIOrderRequest AI下单请求
type AIOrderRequest struct {
	UserID      string                 `json:"user_id"`
	UserContext map[string]interface{} `json:"user_context"`
	Budget      float64                `json:"budget"`
}

// AIOrderResponse AI下单响应
type AIOrderResponse struct {
	Success        bool     `json:"success"`
	Orders         []*Order `json:"orders"`
	TotalAmount    float64  `json:"total_amount"`
	Recommendation string   `json:"recommendation"`
}

// CacheItem 缓存项
type CacheItem struct {
	Data      interface{}   `json:"data"`
	Timestamp time.Time     `json:"timestamp"`
	Expire    time.Duration `json:"expire"`
}

// ============================ 全局变量和初始化 ============================

var (
	// 内存存储
	orders          = make(map[string]*Order)
	products        = make(map[string]*Product)
	seckillStock    = make(map[string]int)
	productCache    = make(map[string]*CacheItem)
	hotProductCache *CacheItem
	userRateLimit   = make(map[string]time.Time)

	// 锁
	orderMutex     sync.RWMutex
	productMutex   sync.RWMutex
	seckillMutex   sync.RWMutex
	cacheMutex     sync.RWMutex
	rateLimitMutex sync.RWMutex
)

// 初始化测试数据
func init() {
	// 初始化商品数据
	products = map[string]*Product{
		"p001": {
			ID:           "p001",
			Name:         "iPhone 15 Pro",
			Price:        7999.00,
			Stock:        1000,
			IsHot:        true,
			SeckillStock: 100,
			SeckillPrice: 6999.00,
		},
		"p002": {
			ID:           "p002",
			Name:         "MacBook Pro",
			Price:        12999.00,
			Stock:        500,
			IsHot:        true,
			SeckillStock: 50,
			SeckillPrice: 11999.00,
		},
		"p003": {
			ID:           "p003",
			Name:         "AirPods Pro",
			Price:        1899.00,
			Stock:        2000,
			IsHot:        false,
			SeckillStock: 200,
			SeckillPrice: 1599.00,
		},
		"p004": {
			ID:           "p004",
			Name:         "iPad Air",
			Price:        4399.00,
			Stock:        800,
			IsHot:        true,
			SeckillStock: 80,
			SeckillPrice: 3999.00,
		},
	}

	// 初始化秒杀库存
	for _, product := range products {
		seckillStock[product.ID] = product.SeckillStock
	}

	log.Println("系统初始化完成，测试数据已加载")
}

// ============================ 工具函数 ============================

func generateOrderID() string {
	return fmt.Sprintf("ORDER%d%d", time.Now().Unix(), rand.Intn(1000))
}

func generateToken() string {
	return fmt.Sprintf("TOKEN%d", time.Now().UnixNano())
}

func isRateLimited(userID string) bool {
	rateLimitMutex.Lock()
	defer rateLimitMutex.Unlock()

	now := time.Now()
	if lastTime, exists := userRateLimit[userID]; exists {
		if now.Sub(lastTime) < time.Second {
			return true
		}
	}
	userRateLimit[userID] = now
	return false
}

// ============================ 02-生成订单模块 ============================

func createNormalOrder(userID, productID string, quantity int) (*Order, error) {
	productMutex.RLock()
	product, exists := products[productID]
	productMutex.RUnlock()

	if !exists {
		return nil, fmt.Errorf("商品不存在")
	}

	if quantity <= 0 {
		return nil, fmt.Errorf("购买数量必须大于0")
	}

	productMutex.Lock()
	if product.Stock < quantity {
		productMutex.Unlock()
		return nil, fmt.Errorf("库存不足，当前库存: %d", product.Stock)
	}
	product.Stock -= quantity
	productMutex.Unlock()

	order := &Order{
		ID:          generateOrderID(),
		UserID:      userID,
		ProductID:   productID,
		ProductName: product.Name,
		Quantity:    quantity,
		TotalPrice:  product.Price * float64(quantity),
		Status:      "created",
		CreatedAt:   time.Now(),
		OrderType:   "normal",
	}

	orderMutex.Lock()
	orders[order.ID] = order
	orderMutex.Unlock()

	// 失效商品缓存
	invalidateProductCache(productID)

	log.Printf("普通订单创建成功: %s, 用户: %s, 商品: %s, 数量: %d, 金额: %.2f",
		order.ID, userID, product.Name, quantity, order.TotalPrice)

	return order, nil
}

// ============================ 04-秒杀活动模块 ============================

func createSeckillOrder(userID, productID string) (*SeckillResult, error) {
	// 频率限制
	if isRateLimited(userID) {
		return &SeckillResult{
			Success: false,
			Message: "请求过于频繁，请稍后再试",
		}, nil
	}

	productMutex.RLock()
	product, exists := products[productID]
	productMutex.RUnlock()

	if !exists {
		return &SeckillResult{
			Success: false,
			Message: "商品不存在",
		}, nil
	}

	seckillMutex.Lock()
	defer seckillMutex.Unlock()

	currentStock := seckillStock[productID]
	if currentStock <= 0 {
		return &SeckillResult{
			Success: false,
			Message: "秒杀已结束，商品已售罄",
		}, nil
	}

	// 扣减秒杀库存
	seckillStock[productID] = currentStock - 1

	// 创建秒杀订单
	order := &Order{
		ID:          generateOrderID(),
		UserID:      userID,
		ProductID:   productID,
		ProductName: product.Name,
		Quantity:    1,
		TotalPrice:  product.SeckillPrice,
		Status:      "seckill_created",
		CreatedAt:   time.Now(),
		OrderType:   "seckill",
	}

	orderMutex.Lock()
	orders[order.ID] = order
	orderMutex.Unlock()

	// 失效商品缓存
	invalidateProductCache(productID)

	log.Printf("秒杀订单创建成功: %s, 用户: %s, 商品: %s, 秒杀价: %.2f",
		order.ID, userID, product.Name, product.SeckillPrice)

	return &SeckillResult{
		Success: true,
		OrderID: order.ID,
		Message: "秒杀成功，请在15分钟内完成支付",
	}, nil
}

// ============================ 08-BFF缓存一致模块 ============================

func getProductWithCache(productID string) (*Product, error) {
	cacheKey := "product_" + productID

	// 先查缓存
	cacheMutex.RLock()
	if item, exists := productCache[cacheKey]; exists {
		if time.Since(item.Timestamp) < item.Expire {
			cacheMutex.RUnlock()
			log.Printf("缓存命中: %s", productID)
			return item.Data.(*Product), nil
		}
	}
	cacheMutex.RUnlock()

	// 缓存未命中，查询数据
	productMutex.RLock()
	product, exists := products[productID]
	productMutex.RUnlock()

	if !exists {
		return nil, fmt.Errorf("商品不存在")
	}

	// 更新缓存
	cacheMutex.Lock()
	productCache[cacheKey] = &CacheItem{
		Data:      product,
		Timestamp: time.Now(),
		Expire:    time.Minute * 5, // 5分钟缓存
	}
	cacheMutex.Unlock()

	log.Printf("缓存更新: %s", productID)
	return product, nil
}

func invalidateProductCache(productID string) {
	cacheKey := "product_" + productID
	cacheMutex.Lock()
	delete(productCache, cacheKey)
	cacheMutex.Unlock()
	log.Printf("缓存失效: %s", productID)
}

// ============================ 09-热门商品模块 ============================

func getHotProducts() []*Product {
	cacheMutex.RLock()
	if hotProductCache != nil && time.Since(hotProductCache.Timestamp) < hotProductCache.Expire {
		cacheMutex.RUnlock()
		log.Println("热门商品缓存命中")
		return hotProductCache.Data.([]*Product)
	}
	cacheMutex.RUnlock()

	// 查询热门商品
	var hotProducts []*Product
	productMutex.RLock()
	for _, product := range products {
		if product.IsHot {
			hotProducts = append(hotProducts, product)
		}
	}
	productMutex.RUnlock()

	// 更新缓存
	cacheMutex.Lock()
	hotProductCache = &CacheItem{
		Data:      hotProducts,
		Timestamp: time.Now(),
		Expire:    time.Minute * 2, // 2分钟缓存
	}
	cacheMutex.Unlock()

	log.Println("热门商品缓存更新")
	return hotProducts
}

// ============================ 10-AI正向下单模块 ============================

func createAIOrder(req *AIOrderRequest) (*AIOrderResponse, error) {
	// AI推荐逻辑
	recommendations := getAIRecommendations(req)
	if len(recommendations) == 0 {
		return &AIOrderResponse{
			Success:        false,
			Recommendation: "很抱歉，没有找到适合您的商品推荐",
		}, nil
	}

	var createdOrders []*Order
	totalAmount := 0.0

	// 创建推荐商品的订单
	for _, product := range recommendations {
		order, err := createNormalOrder(req.UserID, product.ID, 1)
		if err != nil {
			log.Printf("AI订单创建失败: %v", err)
			continue
		}
		createdOrders = append(createdOrders, order)
		totalAmount += order.TotalPrice

		// 检查预算
		if totalAmount > req.Budget && req.Budget > 0 {
			break
		}
	}

	if len(createdOrders) == 0 {
		return &AIOrderResponse{
			Success:        false,
			Recommendation: "订单创建失败，请稍后重试",
		}, nil
	}

	recommendationMsg := fmt.Sprintf("根据您的偏好，AI为您推荐了%d件商品，总金额%.2f元",
		len(createdOrders), totalAmount)

	return &AIOrderResponse{
		Success:        true,
		Orders:         createdOrders,
		TotalAmount:    totalAmount,
		Recommendation: recommendationMsg,
	}, nil
}

func getAIRecommendations(req *AIOrderRequest) []*Product {
	// 模拟AI推荐算法
	// 实际应用中这里会调用机器学习模型
	var recommendations []*Product

	productMutex.RLock()
	defer productMutex.RUnlock()

	// 简单的推荐逻辑
	for _, product := range products {
		// 根据用户上下文进行推荐
		if interest, ok := req.UserContext["interest"]; ok {
			if interest == "tech" && (product.ID == "p001" || product.ID == "p002") {
				recommendations = append(recommendations, product)
			} else if interest == "audio" && product.ID == "p003" {
				recommendations = append(recommendations, product)
			}
		} else {
			// 默认推荐热门商品
			if product.IsHot {
				recommendations = append(recommendations, product)
			}
		}

		if len(recommendations) >= 3 { // 最多推荐3个商品
			break
		}
	}

	return recommendations
}

// ============================ 11-订单流程模块 ============================

func getOrder(orderID string) (*Order, error) {
	orderMutex.RLock()
	defer orderMutex.RUnlock()

	order, exists := orders[orderID]
	if !exists {
		return nil, fmt.Errorf("订单不存在")
	}
	return order, nil
}

func updateOrderStatus(orderID, status string) error {
	orderMutex.Lock()
	defer orderMutex.Unlock()

	order, exists := orders[orderID]
	if !exists {
		return fmt.Errorf("订单不存在")
	}

	order.Status = status
	log.Printf("订单状态更新: %s -> %s", orderID, status)
	return nil
}

func getUserOrders(userID string) []*Order {
	orderMutex.RLock()
	defer orderMutex.RUnlock()

	var userOrders []*Order
	for _, order := range orders {
		if order.UserID == userID {
			userOrders = append(userOrders, order)
		}
	}
	return userOrders
}

// ============================ HTTP 处理器 ============================

func handleCreateOrder(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	userID := r.FormValue("user_id")
	productID := r.FormValue("product_id")
	quantityStr := r.FormValue("quantity")

	if userID == "" || productID == "" || quantityStr == "" {
		http.Error(w, "Missing parameters: user_id, product_id, quantity required", http.StatusBadRequest)
		return
	}

	quantity, err := strconv.Atoi(quantityStr)
	if err != nil || quantity <= 0 {
		http.Error(w, "Invalid quantity", http.StatusBadRequest)
		return
	}

	order, err := createNormalOrder(userID, productID, quantity)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(order)
}

func handleSeckillOrder(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	var req SeckillRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "Invalid request body", http.StatusBadRequest)
		return
	}

	result, err := createSeckillOrder(req.UserID, req.ProductID)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(result)
}

func handleAIOrder(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	var req AIOrderRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "Invalid request body", http.StatusBadRequest)
		return
	}

	response, err := createAIOrder(&req)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(response)
}

func handleGetProduct(w http.ResponseWriter, r *http.Request) {
	productID := r.URL.Query().Get("id")
	if productID == "" {
		http.Error(w, "Missing product id", http.StatusBadRequest)
		return
	}

	product, err := getProductWithCache(productID)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(product)
}

func handleGetHotProducts(w http.ResponseWriter, r *http.Request) {
	hotProducts := getHotProducts()
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(hotProducts)
}

func handleGetOrder(w http.ResponseWriter, r *http.Request) {
	orderID := r.URL.Query().Get("id")
	if orderID == "" {
		http.Error(w, "Missing order id", http.StatusBadRequest)
		return
	}

	order, err := getOrder(orderID)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(order)
}

func handleGetUserOrders(w http.ResponseWriter, r *http.Request) {
	userID := r.URL.Query().Get("user_id")
	if userID == "" {
		http.Error(w, "Missing user id", http.StatusBadRequest)
		return
	}

	userOrders := getUserOrders(userID)
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(userOrders)
}

func handleInvalidateCache(w http.ResponseWriter, r *http.Request) {
	productID := r.URL.Query().Get("product_id")
	if productID == "" {
		http.Error(w, "Missing product id", http.StatusBadRequest)
		return
	}

	invalidateProductCache(productID)
	w.WriteHeader(http.StatusOK)
	fmt.Fprintf(w, "Cache invalidated for product: %s", productID)
}

// ============================ 主函数 ============================

func main() {
	// 设置路由
	http.HandleFunc("/order/create", handleCreateOrder)
	http.HandleFunc("/order/seckill", handleSeckillOrder)
	http.HandleFunc("/order/ai", handleAIOrder)
	http.HandleFunc("/order", handleGetOrder)
	http.HandleFunc("/orders/user", handleGetUserOrders)
	http.HandleFunc("/product", handleGetProduct)
	http.HandleFunc("/products/hot", handleGetHotProducts)
	http.HandleFunc("/cache/invalidate", handleInvalidateCache)

	// 健康检查
	http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)
		fmt.Fprint(w, `{"status": "ok", "timestamp": "`+time.Now().Format(time.RFC3339)+`"}`)
	})

	// 首页
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/html")
		fmt.Fprint(w, `
<!DOCTYPE html>
<html>
<head>
    <title>电商系统 API</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; }
        .endpoint { background: #f5f5f5; padding: 10px; margin: 10px 0; border-left: 4px solid #007bff; }
    </style>
</head>
<body>
    <h1>电商系统 API 服务</h1>
    <p>系统已启动，可用接口:</p>
    
    <div class="endpoint">
        <strong>POST /order/create</strong> - 创建普通订单<br>
        参数: user_id, product_id, quantity
    </div>
    
    <div class="endpoint">
        <strong>POST /order/seckill</strong> - 秒杀订单<br>
        JSON: {"user_id": "xxx", "product_id": "xxx"}
    </div>
    
    <div class="endpoint">
        <strong>POST /order/ai</strong> - AI智能下单<br>
        JSON: {"user_id": "xxx", "user_context": {}, "budget": 1000}
    </div>
    
    <div class="endpoint">
        <strong>GET /order?id=ORDER123</strong> - 查询订单
    </div>
    
    <div class="endpoint">
        <strong>GET /orders/user?user_id=xxx</strong> - 查询用户订单
    </div>
    
    <div class="endpoint">
        <strong>GET /product?id=p001</strong> - 查询商品信息
    </div>
    
    <div class="endpoint">
        <strong>GET /products/hot</strong> - 获取热门商品
    </div>
    
    <div class="endpoint">
        <strong>POST /cache/invalidate?product_id=p001</strong> - 失效缓存
    </div>
    
    <div class="endpoint">
        <strong>GET /health</strong> - 健康检查
    </div>
</body>
</html>
`)
	})

	port := ":8080"
	log.Printf("🚀 服务器启动在 http://localhost%s", port)
	log.Println("📋 可用接口:")
	log.Println("   POST /order/create     - 创建普通订单")
	log.Println("   POST /order/seckill    - 秒杀订单")
	log.Println("   POST /order/ai         - AI智能下单")
	log.Println("   GET  /order            - 查询订单")
	log.Println("   GET  /orders/user      - 查询用户订单")
	log.Println("   GET  /product          - 查询商品信息")
	log.Println("   GET  /products/hot     - 获取热门商品")
	log.Println("   POST /cache/invalidate - 失效缓存")
	log.Println("   GET  /health           - 健康检查")

	if err := http.ListenAndServe(port, nil); err != nil {
		log.Fatal("服务器启动失败:", err)
	}
}
